package app.authorization.config;

import com.dj.gateway.app.authorization.handler.CustomServerAccessDeniedHandler;
import com.dj.gateway.app.authorization.handler.CustomServerAuthenticationEntryPoint;
import com.dj.gateway.app.authorization.manager.WebfluxReactiveAuthorizationManager;
import com.dj.gateway.app.authorization.properties.SecurityProperties;
import com.dj.gateway.app.authorization.properties.WhiteIpProperties;
import com.dj.gateway.app.filter.CorsWebFilter;
import com.dj.gateway.app.filter.RequestLogFilter;
import com.dj.gateway.app.filter.ResponseLogFilter;
import com.dj.gateway.app.filter.UserInfoTransferFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.http.HttpMethod;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@EnableWebFluxSecurity
public class SecurityConfig {

//    @Autowired
//    private CorsWebFilter corsFilter;

    @Autowired
    private RedisConnectionFactory connectionFactory;

    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    public ErrorWebExceptionHandler errorWebExceptionHandler;

    @Autowired
    private WhiteIpProperties whiteIpProperties;
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {

        http.authorizeExchange().pathMatchers(HttpMethod.OPTIONS).permitAll()
                .anyExchange().access(reactiveAuthorizationManager())
                .and().exceptionHandling()
                .authenticationEntryPoint(new CustomServerAuthenticationEntryPoint())
                .accessDeniedHandler(new CustomServerAccessDeniedHandler())
                .and().cors().and().csrf().disable();
        http.addFilterAfter(new RequestLogFilter(), SecurityWebFiltersOrder.FIRST);
        http.addFilterAt(new CorsWebFilter(), SecurityWebFiltersOrder.CORS);
        http.addFilterAfter(new UserInfoTransferFilter(), SecurityWebFiltersOrder.AUTHORIZATION);
        http.addFilterAt(new ResponseLogFilter(), SecurityWebFiltersOrder.FIRST);
        return http.build();
    }

    /**
     * 注入授权管理器
     * @return
     */
    @Bean
    public ReactiveAuthorizationManager reactiveAuthorizationManager(){
        WebfluxReactiveAuthorizationManager webfluxReactiveAuthorizationManager
                = new WebfluxReactiveAuthorizationManager(connectionFactory, securityProperties,whiteIpProperties);
        return webfluxReactiveAuthorizationManager;
    }
}
